<script lang="ts" setup>
import { reactive, watch } from 'vue';
import {
  Loading as AppNutIconLoading,
  Microphone as AppNutIconMicrophone,
} from '@nutui/icons-vue-taro';
import { showToast } from '@tarojs/taro';
import startRecordAudio from 'gdt-jsapi/startRecordAudio';
import stopRecordAudio from 'gdt-jsapi/stopRecordAudio';
import { DOWNLOAD_MEDIA } from '/@/api/modules/ding-talk/dd-user';
import { getSysImgUrl } from '/@/utils/index';
import { onMounted } from 'vue';

const props = withDefaults(
  defineProps<{
    /**
     * 音频url
     */
    url?: string;
    /**
     * 只读
     */
    readonly?: boolean;
  }>(),
  {
    url: '',
    readonly: false,
  },
);

const emits = defineEmits<{
  (e: 'change', filePath: string): void;
}>();

const state = reactive<{
  /**
   * 录音中
   */
  inRecord: boolean;
  /**
   * 音频在服务端的标识
   */
  mediaId: string;
  /**
   * 音频文件地址
   */
  filePath: string;
}>({
  inRecord: false,
  mediaId: '',
  filePath: '',
});

/**
 * @function 录音
 */
function handleRecorder() {
  if (!state.inRecord) {
    startRecordAudio({})
      .then(() => {
        state.inRecord = true;

        setTimeout(() => {
          stopRecordAudio({})
            .then((res) => {
              showToast({ title: '录音已超过60秒, 将停止录音!', icon: 'error' });
              state.inRecord = false;
              state.mediaId = res.mediaId;
              download(state.mediaId);
            })
            .catch((err) => {
              showToast({ title: err, icon: 'error' });
            });
        }, 59000);
      })
      .catch((err) => {
        showToast({ title: err, icon: 'error' });
      });
  } else {
    stopRecordAudio({})
      .then((res) => {
        state.inRecord = false;
        state.mediaId = res.mediaId;
        download(state.mediaId);
      })
      .catch((err) => {
        showToast({ title: err, icon: 'error' });
      });
  }
}

/**
 * @function 下载录音
 * @param mediaId -音频在服务端的标识
 */
function download(mediaId: string) {
  if (!mediaId) return;

  DOWNLOAD_MEDIA({
    mediaId,
  }).then((res) => {
    state.filePath = res.filePath;
    emits('change', state.filePath);
  });
}

watch(props, (newProps) => {
  if (newProps.url) {
    state.filePath = newProps.url;
  }
});

onMounted(() => {
  state.filePath = props.url;
});
</script>

<template>
  <view class="app-dd-record-audio">
    <audio
      class="app-dd-record-audio__audio"
      v-if="state.filePath"
      :src="getSysImgUrl(state.filePath)"
    />
    <nut-button v-if="!props.readonly" size="small" type="info" @click="handleRecorder()">
      <template #icon>
        <app-nut-icon-loading v-if="state.inRecord" />
        <app-nut-icon-microphone v-else />
      </template>
      {{ state.inRecord ? '正在录音' : '点击开始说话' }}
    </nut-button>
  </view>
</template>

<style lang="scss">
.app-dd-record-audio {
  &__audio {
    margin-bottom: 10px;
  }
}
</style>
